#include <glut.h>
#include <iostream>
#include <Windows.h>
#include <cmath>
#include "baseShape.h"
#include "Helicopter.h"
#include "Scene.h"
#include "Camera.h"

using namespace std;
const int initWindowWidth=700,initWindowHeight=700;
const char *initWindowTitle="MyHelicopter";

const GLdouble MoveLen=.3;
const GLdouble TurnAngle=3;

bool bOpenLight=true;
bool bLight0=true;

bool bWireframe=false;


Helicopter apache;
Scene s;
Camera camera;

void drawString(const char* str) 
{
	static int isFirstCall=1;
	static GLuint lists;

	if(isFirstCall)
	{ 
		isFirstCall=0;
		lists=glGenLists(255);
		wglUseFontBitmaps(wglGetCurrentDC(),0,255,lists);
	}

	for(;*str!='\0';++str)
		glCallList(lists+*str);
}

void DisplayFunc()
{
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	//print name
	{
		glPushMatrix();
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(0,1,1,10000);

		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		glRasterPos2f(.8f,.95f);
		glTranslated(.8,.9,0);
		glColor3ub(255u,0,0);
		drawString("Fan Yinlu");
		
		glLoadIdentity();
		glRasterPos2f(-.95,-.95);
		glTranslated(-.95,-.95,0);
		static char buf[128];
		sprintf(buf,"Speed-Front:%.02f Meter/Sec\n",apache.GetSpeedX());
		drawString(buf);

		glLoadIdentity();
		glRasterPos2f(-.95,-.99);
		glTranslated(-.95,-.99,0);
		sprintf(buf,"Speed-Up:%.02f Meter/Sec",apache.GetSpeedZ());
		drawString(buf);

		glLoadIdentity();
		glRasterPos2f(-.95,-.90);
		glTranslated(-.95,-.90,0);
		sprintf(buf,"Height:%.02f Meter",apache.m_Position[2]);
		drawString(buf);

		glPopMatrix();
	}
	
	//draw scene and helicopter

	camera.draw();
	s.draw();
	apache.draw();

	glutSwapBuffers();
}

void KeyBoardFunc(unsigned char key,int MouseX,int MouseY)
{
	switch(key)
	{
// 	case 'w':
// 		apache.xSpeedUp();
// 		break;
// 	case 's':
// 		apache.xSpeedDown();
// 		break;
// 	case 'q':
// 		apache.ySpeedUp();
// 		break;
// 	case 'e':
// 		apache.ySpeedDown();
// 		break;
	case 'a':
		apache.zSpeedUp();
		break;
	case 'z':
		apache.zSpeedDown();
		break;
	case ',':
		camera.zoomin();
		break;
	case '.':
		camera.zoomout();
		break;
	case '1':
		camera.lookAt(apache);
		break;
	case '2':
		camera.lookNull();
		break;
	case 27:
		exit(0);
	default:
		break;
	}
	
}

void SpecialFunc(int key,int MouseX,int MouseY)
{
	switch(key)
	{
	case GLUT_KEY_UP:
		apache.xSpeedUp();
		break;
	case GLUT_KEY_DOWN:
		apache.xSpeedDown();
		break;
	case GLUT_KEY_LEFT:
		apache.TurnLeft();
		break;
	case GLUT_KEY_RIGHT:
		apache.TrunRight();
		break;
	case GLUT_KEY_F2:
		if(bWireframe)
		{
			glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
			bWireframe=false;
		}
		else
		{
			glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
			bWireframe=true;
		}
		
		break;
	case GLUT_KEY_F9:
		if(bOpenLight)
		{
			glDisable(GL_LIGHTING);
			bOpenLight=false;
		}
		else
		{			
			glEnable(GL_LIGHTING);
			bOpenLight=true;
		}
		break;
	case GLUT_KEY_F10:
		if(bLight0)
		{
			glDisable(GL_LIGHT0);
			bLight0=false;
		}
		else
		{
			glEnable(GL_LIGHT0);
			bLight0=true;
		}
		break;
	default:
		break;
	}
}

void TimerFunc(int val)
{
	apache.OnTimer(80);
	glutTimerFunc(80,TimerFunc,val);
}

void MouseFunc(int button,int state,int x,int y)
{
	if(button==0&&state==0)
	{
		camera.beginDrag(x,y);
	}
	if(button==0&&state==1)
	{
		camera.endDrag();
	}
}

void MotionFunc(int x,int y)
{
	camera.drag(x,y);
}

void printUsage()
{
	cout<<"Up(w) move forward"<<endl;
	cout<<"Down(s) move backword"<<endl;
	cout<<"Left(a) turn left"<<endl;
	cout<<"Right(d) turn right"<<endl;
	cout<<"Q move left"<<endl;
	cout<<"E move right"<<endl;
	cout<<"R raise up"<<endl;
	cout<<"F fall down"<<endl;
	cout<<"1 Fixed camera"<<endl;
	cout<<"2 Camera view follows object"<<endl;
	cout<<"F9 Light(s) on/off"<<endl;
	cout<<"F10 Switch using lighting/shading"<<endl;
	cout<<"Esc exit"<<endl;
}

int main(int argc,char *argv[])
{
	printUsage();
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE );
	glutInitWindowPosition((GetSystemMetrics(SM_CXSCREEN)-initWindowWidth)/2, (GetSystemMetrics(SM_CYSCREEN)-initWindowHeight)/2);
	glutInitWindowSize(initWindowWidth, initWindowHeight);
	glutCreateWindow(initWindowTitle);
	glutDisplayFunc(DisplayFunc);
	glutIdleFunc(DisplayFunc);
	glutKeyboardFunc(KeyBoardFunc);
	glutSpecialFunc(SpecialFunc);
	glutMouseFunc(MouseFunc);
	glutMotionFunc(MotionFunc);
	glutTimerFunc(10,TimerFunc,0);
	apache.init();
	s.init();
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHTING);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_TEXTURE_2D);
	glClearColor(1,1,1,0);
	glutMainLoop();	
	return 0;
}